/**
  * @(#)Enumeration.java
  *
  * Provide a common enumeration implementation which doesn't depend on the
  * Java enum type. This is so that the enum class can be extensible at runtime
  * by registering additional instances of the type.
  *
  * @author Course Scheduler Team
  * 
  * @license GNU General Public License version 3 (GPLv3)
  *
  * This file is part of Course Scheduler, an open source, cross platform
  * course scheduling tool, configurable for most universities.
  *
  * Copyright (C) 2010-2012 Course Scheduler Team
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation, either version 3 of the License, or
  * (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  * 
  */
package com.pollicitus.scheduler.util;

import com.pollicitus.scheduler.util.Enumeration;

/**
 * Provide a common enumeration implementation which doesn't depend on the
 * Java enum type. This is so that the enum class can be extensible at runtime
 * by registering additional instances of the type.
 * 
 * @author Course Scheduler Team
 *
 */
public abstract class Enumeration<T extends Enumeration<T>> implements Comparable<T> {

	/**
	 * The most recent revision in which this file was changed in the source control system
	 */
	public static final String _revision = "$LastChangedRevision: 539 $";
	
	/**
	 * The date on which this file was last changed and submitted to source control
	 */
	public static final String _date = "$LastChangedDate: 2011-11-19 23:14:16 -0500 (Sat, 19 Nov 2011) $";
	
	/**
	 * The user which last changed the file and committed the change to source control
	 */
	public static final String _author = "$LastChangedBy: mike@pollicitus.com $";
	
	/**
	 * The URL which can be used to access this specific file within the source control system
	 */
	public static final String _headURL = "$HeadURL: https://courseschedulerx.googlecode.com/svn/trunk/course-scheduler/course-scheduler-core/src/main/java/com/pollicitus/scheduler/util/Enumeration.java $";
	
	/**
	 * The source control file ID, comprised of the file name, latest revision, last changed date, and submitting user.
	 */
	public static final String _id = "$Id: Enumeration.java 539 2011-11-20 04:14:16Z mike@pollicitus.com $";
	
	//protected enumeration ordinal
	protected int ordinal;
	protected String description;
	protected String name;
	
	/**
	 * Abstract constructor for building the enumeration. Set the internal
	 * ordinal, description, and name attributes then register the enum
	 * instance.
	 * 
	 * @param name the enumeration instance name
	 * @param description the enumeration instance description
	 * @param ordinal the enumeration instance ordinal
	 */
	protected Enumeration(String name, String description, int ordinal){
		this.name = name;
		this.description = description;
		this.ordinal = ordinal;
		register();
	}
	
	/* (non-Javadoc)
	 * @see java.lang.Comparable#compareTo(java.lang.Object)
	 */
	public int compareTo(T t){
		return this.name.compareTo(t.name);
	}
	
	/**
	 * Return the enumeration's ordinal value. The ordinal must remain
	 * constant for a specific enumeration class instance.
	 * 
	 * @return ordinal of the enumeration instance
	 */
	public int ordinal() {
		return ordinal;
	}
	
	/* (non-Javadoc)
	 * @see java.lang.Object#clone()
	 */
	public Object clone() throws CloneNotSupportedException{
		throw new CloneNotSupportedException();
	}
	
	/**
	 * Register an enumeration instance with its parent enumeration class
	 * for use within the application.
	 */
	protected abstract void register();
	
	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString(){
		return description;
	}
	
	/**
	 * Return the enumeration name for this instance
	 * 
	 * @return the enumeration name
	 */
	public String getName(){
		return name;
	}
	
	/**
	 * Return the enumeration description for this instance
	 * 
	 * @return the enumeration description
	 */
	public String getDescription(){
		return description;
	}
	
	/**
	 * Return the enumeration ordinal for this instance
	 * 
	 * @return the enumeration ordinal
	 */
	public int getOrdinal(){
		return ordinal;
	}
}
